WebGL ๋๊ธฐํ ๊ฐ์ฒด์ ๋ํ ์ฌ์ธต ๋ถ์. ํจ์จ์ ์ธ GPU-CPU ๋๊ธฐํ, ์ฑ๋ฅ ์ต์ ํ, ์ต์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก์์์ ์ญํ ์ ํ๊ตฌํฉ๋๋ค.
WebGL ๋๊ธฐํ ๊ฐ์ฒด: ๊ณ ์ฑ๋ฅ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ GPU-CPU ๋๊ธฐํ ๋ง์คํฐํ๊ธฐ
WebGL์ ์ธ๊ณ์์, ๋งค๋๋ฝ๊ณ ๋ฐ์์ฑ์ด ์ข์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌํํ๋ ๊ฒ์ ๊ทธ๋ํฝ ์ฒ๋ฆฌ ์ฅ์น(GPU)์ ์ค์ ์ฒ๋ฆฌ ์ฅ์น(CPU) ๊ฐ์ ํจ์จ์ ์ธ ํต์ ๋ฐ ๋๊ธฐํ์ ๋ฌ๋ ค ์์ต๋๋ค. GPU์ CPU๊ฐ (์ผ๋ฐ์ ์ผ๋ก) ๋น๋๊ธฐ์ ์ผ๋ก ์๋ํ ๋, ๋ณ๋ชฉ ํ์์ ํผํ๊ณ ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ฉฐ ์ฑ๋ฅ์ ๊ทน๋ํํ๊ธฐ ์ํด ์ด๋ค์ ์ํธ ์์ฉ์ ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ฐ๋ก ์ด ์ง์ ์์ WebGL ๋๊ธฐํ ๊ฐ์ฒด๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์ด ์ข ํฉ ๊ฐ์ด๋์์๋ ๋๊ธฐํ ๊ฐ์ฒด์ ๊ฐ๋ , ๊ธฐ๋ฅ, ๊ตฌํ ์ธ๋ถ ์ ๋ณด ๋ฐ WebGL ํ๋ก์ ํธ์์ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๊ธฐ ์ํ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ํ๊ตฌํฉ๋๋ค.
GPU-CPU ๋๊ธฐํ์ ํ์์ฑ ์ดํดํ๊ธฐ
ํ๋์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ข ์ข ๋ณต์กํ ๊ทธ๋ํฝ ๋ ๋๋ง, ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ , ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์๊ตฌํ๋ฉฐ, ์ด๋ฌํ ์์ ๋ค์ ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด GPU๋ก ์คํ๋ก๋๋ฉ๋๋ค. ํํธ CPU๋ ์ฌ์ฉ์ ์ํธ ์์ฉ, ์ ํ๋ฆฌ์ผ์ด์ ๋ก์ง ๋ฐ ๊ธฐํ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ฌํ ๋ถ์ ์ ๊ฐ๋ ฅํ์ง๋ง ๋๊ธฐํ์ ํ์์ฑ์ ์ผ๊ธฐํฉ๋๋ค. ์ ์ ํ ๋๊ธฐํ๊ฐ ์์ผ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค:
- ๋ฐ์ดํฐ ๊ฒฝ์(Data Races): CPU๊ฐ GPU๊ฐ ์์ง ์์ ์ค์ธ ๋ฐ์ดํฐ์ ์ ๊ทผํ์ฌ ์ผ๊ด์ฑ์ด ์๊ฑฐ๋ ์๋ชป๋ ๊ฒฐ๊ณผ๋ฅผ ์ด๋ํ ์ ์์ต๋๋ค.
- ์ง์ฐ(Stalls): CPU๊ฐ ๊ณ์ ์งํํ๊ธฐ ์ ์ GPU๊ฐ ์์ ์ ์๋ฃํ๊ธฐ๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ง์ฐ์ ์ ๋ฐํ๊ณ ์ ๋ฐ์ ์ธ ์ฑ๋ฅ์ ์ ํ์ํต๋๋ค.
- ๋ฆฌ์์ค ์ถฉ๋(Resource Conflicts): CPU์ GPU๊ฐ ๋์์ ๋์ผํ ๋ฆฌ์์ค์ ์ ๊ทผํ๋ ค๊ณ ์๋ํ์ฌ ์์ธกํ ์ ์๋ ๋์์ ์ ๋ฐํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์, ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฑ์ ์ ์งํ๊ณ ์ต์ ์ ์ฑ๋ฅ์ ๋ฌ์ฑํ๊ธฐ ์ํด์๋ ๊ฐ๋ ฅํ ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ๊ตฌ์ถํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค.
WebGL ๋๊ธฐํ ๊ฐ์ฒด ์๊ฐ
WebGL ๋๊ธฐํ ๊ฐ์ฒด๋ CPU์ GPU ๊ฐ์ ์์ ์ ๋ช ์์ ์ผ๋ก ๋๊ธฐํํ๋ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํฉ๋๋ค. ๋๊ธฐํ ๊ฐ์ฒด๋ ํ์ค(fence) ์ญํ ์ ํ์ฌ GPU ๋ช ๋ น์ด ์งํฉ์ ์๋ฃ๋ฅผ ์๋ฆฝ๋๋ค. ๊ทธ๋ฌ๋ฉด CPU๋ ์ด ํ์ค๋ฅผ ๊ธฐ๋ค๋ ค ํด๋น ๋ช ๋ น์ด๋ค์ด ์คํ์ ๋ง์ณค๋์ง ํ์ธํ ํ ๋ค์ ์์ ์ ์งํํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ์๊ฐํด๋ณด์ธ์: ๋น์ ์ด ํผ์๋ฅผ ์ฃผ๋ฌธํ๋ค๊ณ ์์ํด๋ณด์ธ์. GPU๋ (๋น๋๊ธฐ์ ์ผ๋ก ์ผํ๋) ํผ์ ์ ์์์ด๊ณ , CPU๋ ๋จน๊ธฐ ์ํด ๊ธฐ๋ค๋ฆฌ๋ ๋น์ ์ ๋๋ค. ๋๊ธฐํ ๊ฐ์ฒด๋ ํผ์๊ฐ ์ค๋น๋์์ ๋ ๋ฐ๋ ์๋ฆผ๊ณผ ๊ฐ์ต๋๋ค. ๋น์ (CPU)์ ๊ทธ ์๋ฆผ์ ๋ฐ๊ธฐ ์ ๊น์ง๋ ํผ์ ์กฐ๊ฐ์ ์ง์ผ๋ ค ํ์ง ์์ ๊ฒ์ ๋๋ค.
๋๊ธฐํ ๊ฐ์ฒด์ ์ฃผ์ ํน์ง:
- ํ์ค ๋๊ธฐํ(Fence Synchronization): ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด GPU ๋ช ๋ น์ด ์คํธ๋ฆผ์ 'ํ์ค'๋ฅผ ์ฝ์ ํ ์ ์์ต๋๋ค. ์ด ํ์ค๋ ์ด์ ์ ๋ชจ๋ ๋ช ๋ น์ด๊ฐ ์คํ๋ ํน์ ์์ ์ ์๋ฆฝ๋๋ค.
- CPU ๋๊ธฐ(CPU Wait): CPU๋ ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ค๋ฆด ์ ์์ผ๋ฉฐ, ํ์ค๊ฐ GPU์ ์ํด ์ ํธ๋ฅผ ๋ฐ์ ๋๊น์ง ์คํ์ ์ฐจ๋จํฉ๋๋ค.
- ๋น๋๊ธฐ ์์ (Asynchronous Operation): ๋๊ธฐํ ๊ฐ์ฒด๋ ๋น๋๊ธฐ ํต์ ์ ๊ฐ๋ฅํ๊ฒ ํ์ฌ, ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ๋ณด์ฅํ๋ฉด์ GPU์ CPU๊ฐ ๋์์ ์๋ํ ์ ์๋๋ก ํฉ๋๋ค.
WebGL์์ ๋๊ธฐํ ๊ฐ์ฒด ์์ฑ ๋ฐ ์ฌ์ฉํ๊ธฐ
WebGL ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋จ๊ณ๋ณ ๊ฐ์ด๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
1๋จ๊ณ: ๋๊ธฐํ ๊ฐ์ฒด ์์ฑํ๊ธฐ
์ฒซ ๋ฒ์งธ ๋จ๊ณ๋ `gl.createSync()` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋๋ค:
const sync = gl.createSync();
์ด๊ฒ์ ๋ถํฌ๋ช ํ(opaque) ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ์์ง ์ด๊ธฐ ์ํ๋ ์ฐ๊ฒฐ๋์ด ์์ง ์์ต๋๋ค.
2๋จ๊ณ: ํ์ค ๋ช ๋ น์ด ์ฝ์ ํ๊ธฐ
๋ค์์ผ๋ก, GPU ๋ช ๋ น์ด ์คํธ๋ฆผ์ ํ์ค ๋ช ๋ น์ด๋ฅผ ์ฝ์ ํด์ผ ํฉ๋๋ค. ์ด๋ `gl.fenceSync()` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฉ๋๋ค:
gl.fenceSync(sync, 0);
`gl.fenceSync()` ํจ์๋ ๋ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์ต๋๋ค:
- `sync`: ํ์ค์ ์ฐ๊ฒฐํ ๋๊ธฐํ ๊ฐ์ฒด์ ๋๋ค.
- `flags`: ํฅํ ์ฌ์ฉ์ ์ํด ์์ฝ๋์ด ์์ต๋๋ค. ๋ฐ๋์ 0์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
์ด ๋ช ๋ น์ด๋ GPU์๊ฒ ๋ช ๋ น์ด ์คํธ๋ฆผ์ ๋ชจ๋ ์ด์ ๋ช ๋ น์ด๊ฐ ์๋ฃ๋๋ฉด ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์ ํธ ์ํ(signaled state)๋ก ์ค์ ํ๋๋ก ์ง์ํฉ๋๋ค.
3๋จ๊ณ: ๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐํ๊ธฐ (CPU ์ธก)
CPU๋ `gl.clientWaitSync()` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋๊ธฐํ ๊ฐ์ฒด๊ฐ ์ ํธ๋ฅผ ๋ฐ์ ๋๊น์ง ๊ธฐ๋ค๋ฆด ์ ์์ต๋๋ค:
const timeout = 5000; // ํ์์์ (๋ฐ๋ฆฌ์ด ๋จ์)
const flags = 0;
const status = gl.clientWaitSync(sync, flags, timeout);
if (status === gl.TIMEOUT_EXPIRED) {
console.warn("๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐ ์๊ฐ ์ด๊ณผ!");
} else if (status === gl.CONDITION_SATISFIED) {
console.log("๋๊ธฐํ ๊ฐ์ฒด ์ ํธ๋จ!");
// GPU ๋ช
๋ น์ด ์๋ฃ๋์์ผ๋ฏ๋ก CPU ์์
์งํ
} else if (status === gl.WAIT_FAILED) {
console.error("๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐ ์คํจ!");
}
`gl.clientWaitSync()` ํจ์๋ ์ธ ๊ฐ์ ์ธ์๋ฅผ ๋ฐ์ต๋๋ค:
- `sync`: ๋๊ธฐํ ๋๊ธฐํ ๊ฐ์ฒด์ ๋๋ค.
- `flags`: ํฅํ ์ฌ์ฉ์ ์ํด ์์ฝ๋์ด ์์ต๋๋ค. ๋ฐ๋์ 0์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.
- `timeout`: ๋๊ธฐํ ์ต๋ ์๊ฐ (๋๋ ธ์ด ๋จ์). ๊ฐ 0์ ์์ํ ๊ธฐ๋ค๋ฆฝ๋๋ค. ์ด ์์ ์์๋ (์ด ์ค๋ํซ์ ๋ช ์์ ์ผ๋ก ํ์๋์ง๋ ์์์ง๋ง ์์์ ์ผ๋ก) ์ฝ๋ ๋ด๋ถ์์ ๋ฐ๋ฆฌ์ด๋ฅผ ๋๋ ธ์ด๋ก ๋ณํํ๊ณ ์์ต๋๋ค.
์ด ํจ์๋ ๋๊ธฐํ ๊ฐ์ฒด๊ฐ ํ์์์ ๊ธฐ๊ฐ ๋ด์ ์ ํธ๋ฅผ ๋ฐ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ์ํ ์ฝ๋๋ฅผ ๋ฐํํฉ๋๋ค.
์ค์ ์ฐธ๊ณ : `gl.clientWaitSync()`๋ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จ(block)ํฉ๋๋ค. ํ ์คํธ๋ ์ฐจ๋จ์ด ๋ถ๊ฐํผํ ์๋๋ฆฌ์ค์๋ ์ ํฉํ ์ ์์ง๋ง, ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ์ ์ธํฐํ์ด์ค๊ฐ ๋ฉ์ถ๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๋น๋๊ธฐ ๊ธฐ์ (๋์ค์ ์ค๋ช )์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค.
4๋จ๊ณ: ๋๊ธฐํ ๊ฐ์ฒด ์ญ์ ํ๊ธฐ
๋๊ธฐํ ๊ฐ์ฒด๊ฐ ๋ ์ด์ ํ์ํ์ง ์์ผ๋ฉด `gl.deleteSync()` ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ์ญ์ ํด์ผ ํฉ๋๋ค:
gl.deleteSync(sync);
์ด๋ ๊ฒ ํ๋ฉด ๋๊ธฐํ ๊ฐ์ฒด์ ๊ด๋ จ๋ ๋ฆฌ์์ค๊ฐ ํด์ ๋ฉ๋๋ค.
๋๊ธฐํ ๊ฐ์ฒด ์ฌ์ฉ์ ์ค์ ์์
๋ค์์ ๋๊ธฐํ ๊ฐ์ฒด๊ฐ ์ ์ฉํ ์ ์๋ ๋ช ๊ฐ์ง ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค์ ๋๋ค:
1. ํ ์ค์ฒ ์ ๋ก๋ ๋๊ธฐํ
GPU์ ํ ์ค์ฒ๋ฅผ ์ ๋ก๋ํ ๋, ํ ์ค์ฒ๋ก ๋ ๋๋งํ๊ธฐ ์ ์ ์ ๋ก๋๊ฐ ์๋ฃ๋์๋์ง ํ์ธํ๊ณ ์ถ์ ์ ์์ต๋๋ค. ์ด๋ ๋น๋๊ธฐ ํ ์ค์ฒ ์ ๋ก๋๋ฅผ ์ฌ์ฉํ ๋ ํนํ ์ค์ํฉ๋๋ค. ์๋ฅผ ๋ค์ด, `image-decode`์ ๊ฐ์ ์ด๋ฏธ์ง ๋ก๋ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์์ปค ์ค๋ ๋์์ ์ด๋ฏธ์ง๋ฅผ ๋์ฝ๋ฉํ ์ ์์ต๋๋ค. ๊ทธ๋ฐ ๋ค์ ๋ฉ์ธ ์ค๋ ๋๋ ์ด ๋ฐ์ดํฐ๋ฅผ WebGL ํ ์ค์ฒ์ ์ ๋ก๋ํฉ๋๋ค. ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ค์ฒ๋ก ๋ ๋๋งํ๊ธฐ ์ ์ ํ ์ค์ฒ ์ ๋ก๋๊ฐ ์๋ฃ๋์๋์ง ํ์ธํ ์ ์์ต๋๋ค.
// CPU: ์ด๋ฏธ์ง ๋ฐ์ดํฐ ๋์ฝ๋ฉ (์์ปค ์ค๋ ๋์์ ๊ฐ๋ฅ)
const imageData = decodeImage(imageURL);
// GPU: ํ
์ค์ฒ ๋ฐ์ดํฐ ์
๋ก๋
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, imageData.width, imageData.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, imageData.data);
// ํ์ค ์์ฑ ๋ฐ ์ฝ์
const sync = gl.createSync();
gl.fenceSync(sync, 0);
// CPU: ํ
์ค์ฒ ์
๋ก๋ ์๋ฃ ๋๊ธฐ (๋์ค์ ์ค๋ช
ํ ๋น๋๊ธฐ ๋ฐฉ์ ์ฌ์ฉ)
waitForSync(sync).then(() => {
// ํ
์ค์ฒ ์
๋ก๋ ์๋ฃ, ๋ ๋๋ง ์งํ
renderScene();
gl.deleteSync(sync);
});
2. ํ๋ ์๋ฒํผ ์ฝ๊ธฐ ๋๊ธฐํ
ํ๋ ์๋ฒํผ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ์ฝ์ด์ผ ํ๋ ๊ฒฝ์ฐ(์: ํ์ฒ๋ฆฌ ๋๋ ๋ถ์), ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ ์ ์ ํ๋ ์๋ฒํผ์ ๋ํ ๋ ๋๋ง์ด ์๋ฃ๋์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ์ง์ฐ ๋ ๋๋ง(deferred rendering) ํ์ดํ๋ผ์ธ์ ๊ตฌํํ๋ ์๋๋ฆฌ์ค๋ฅผ ์๊ฐํด๋ณด์ธ์. ๋ฒ์ , ๊น์ด, ์์๊ณผ ๊ฐ์ ์ ๋ณด๋ฅผ ์ ์ฅํ๊ธฐ ์ํด ์ฌ๋ฌ ํ๋ ์๋ฒํผ์ ๋ ๋๋งํฉ๋๋ค. ์ด๋ฌํ ๋ฒํผ๋ค์ ์ต์ข ์ด๋ฏธ์ง๋ก ํฉ์ฑํ๊ธฐ ์ ์, ๊ฐ ํ๋ ์๋ฒํผ์ ๋ํ ๋ ๋๋ง์ด ์๋ฃ๋์๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
// GPU: ํ๋ ์๋ฒํผ์ ๋ ๋๋ง
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
renderSceneToFramebuffer();
// ํ์ค ์์ฑ ๋ฐ ์ฝ์
const sync = gl.createSync();
gl.fenceSync(sync, 0);
// CPU: ๋ ๋๋ง ์๋ฃ ๋๊ธฐ
waitForSync(sync).then(() => {
// ํ๋ ์๋ฒํผ์์ ๋ฐ์ดํฐ ์ฝ๊ธฐ
const pixels = new Uint8Array(width * height * 4);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
processFramebufferData(pixels);
gl.deleteSync(sync);
});
3. ๋ค์ค ์ปจํ ์คํธ ๋๊ธฐํ
์ฌ๋ฌ WebGL ์ปจํ ์คํธ๊ฐ ๊ด๋ จ๋ ์๋๋ฆฌ์ค(์: ์คํ์คํฌ๋ฆฐ ๋ ๋๋ง)์์๋ ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์ปจํ ์คํธ ๊ฐ์ ์์ ์ ๋๊ธฐํํ ์ ์์ต๋๋ค. ์ด๋ ๋ฉ์ธ ๋ ๋๋ง ์ปจํ ์คํธ์์ ์ฌ์ฉํ๊ธฐ ์ ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ปจํ ์คํธ์์ ํ ์ค์ฒ๋ ์ง์ค๋ฉํธ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๊ณ์ฐํ๋ ๊ฒ๊ณผ ๊ฐ์ ์์ ์ ์ ์ฉํฉ๋๋ค. ๋ณต์กํ ์ ์ฐจ์ ํ ์ค์ฒ๋ฅผ ์์ฑํ๋ ๋ฐ ์ ์ฉ์ธ ์์ฒด WebGL ์ปจํ ์คํธ๋ฅผ ๊ฐ์ง ์์ปค ์ค๋ ๋๊ฐ ์๋ค๊ณ ์์ํด๋ณด์ธ์. ๋ฉ์ธ ๋ ๋๋ง ์ปจํ ์คํธ๋ ์ด๋ฌํ ํ ์ค์ฒ๊ฐ ํ์ํ์ง๋ง, ์์ปค ์ปจํ ์คํธ๊ฐ ์์ฑ์ ์๋ฃํ ๋๊น์ง ๊ธฐ๋ค๋ ค์ผ ํฉ๋๋ค.
๋น๋๊ธฐ ๋๊ธฐํ: ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ ํผํ๊ธฐ
์์ ์ธ๊ธํ๋ฏ์ด, `gl.clientWaitSync()`๋ฅผ ์ง์ ์ฌ์ฉํ๋ฉด ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ฌ ์ข์ง ์์ ์ฌ์ฉ์ ๊ฒฝํ์ ์ด๋ํ ์ ์์ต๋๋ค. ๋ ๋์ ์ ๊ทผ ๋ฐฉ์์ Promise์ ๊ฐ์ ๋น๋๊ธฐ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ๋๊ธฐํ๋ฅผ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋๋ค.
๋ค์์ Promise๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ `waitForSync()` ํจ์๋ฅผ ๊ตฌํํ๋ ์์ ์ ๋๋ค:
function waitForSync(sync) {
return new Promise((resolve, reject) => {
function checkStatus() {
const statusValues = [
gl.SIGNALED,
gl.ALREADY_SIGNALED,
gl.TIMEOUT_EXPIRED,
gl.CONDITION_SATISFIED,
gl.WAIT_FAILED
];
const status = gl.getSyncParameter(sync, gl.SYNC_STATUS, null, 0, new Int32Array(1), 0);
if (statusValues[0] === status[0] || statusValues[1] === status[0]) {
resolve(); // ๋๊ธฐํ ๊ฐ์ฒด๊ฐ ์ ํธ๋ฅผ ๋ณด๋์ต๋๋ค
} else if (statusValues[2] === status[0]) {
reject("๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐ ์๊ฐ ์ด๊ณผ"); // ๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐ ์๊ฐ ์ด๊ณผ
} else if (statusValues[4] === status[0]) {
reject("๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐ ์คํจ");
} else {
// ์์ง ์ ํธ๋์ง ์์, ๋์ค์ ๋ค์ ํ์ธ
requestAnimationFrame(checkStatus);
}
}
checkStatus();
});
}
์ด `waitForSync()` ํจ์๋ ๋๊ธฐํ ๊ฐ์ฒด๊ฐ ์ ํธ๋ฅผ ๋ณด๋ด๋ฉด ํด๊ฒฐ(resolve)๋๊ฑฐ๋ ํ์์์์ด ๋ฐ์ํ๋ฉด ๊ฑฐ๋ถ(reject)๋๋ Promise๋ฅผ ๋ฐํํฉ๋๋ค. ์ด ํจ์๋ `requestAnimationFrame()`์ ์ฌ์ฉํ์ฌ ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ์ฃผ๊ธฐ์ ์ผ๋ก ๋๊ธฐํ ๊ฐ์ฒด์ ์ํ๋ฅผ ํ์ธํฉ๋๋ค.
์ค๋ช :
- `gl.getSyncParameter(sync, gl.SYNC_STATUS)`: ์ด๊ฒ์ด ๋น์ฐจ๋จ ํ์ธ์ ํต์ฌ์ ๋๋ค. CPU๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋๊ธฐํ ๊ฐ์ฒด์ ํ์ฌ ์ํ๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
- `requestAnimationFrame(checkStatus)`: ๋ค์ ๋ธ๋ผ์ฐ์ ๋ฆฌํ์ธํธ(repaint) ์ ์ `checkStatus` ํจ์๊ฐ ํธ์ถ๋๋๋ก ์์ฝํ์ฌ, ๋ธ๋ผ์ฐ์ ๊ฐ ๋ค๋ฅธ ์์ ์ ์ฒ๋ฆฌํ๊ณ ๋ฐ์์ฑ์ ์ ์งํ ์ ์๋๋ก ํฉ๋๋ค.
WebGL ๋๊ธฐํ ๊ฐ์ฒด ์ฌ์ฉ์ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
WebGL ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๋ ค๋ฉด ๋ค์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ณ ๋ คํ์ญ์์ค:
- CPU ๋๊ธฐ ์ต์ํ: ๊ฐ๋ฅํ ํ ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ์ ํผํ์ญ์์ค. Promise๋ ์ฝ๋ฐฑ๊ณผ ๊ฐ์ ๋น๋๊ธฐ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ๋๊ธฐํ๋ฅผ ์ฒ๋ฆฌํ์ญ์์ค.
- ๊ณผ๋ํ ๋๊ธฐํ ํผํ๊ธฐ: ๊ณผ๋ํ ๋๊ธฐํ๋ ๋ถํ์ํ ์ค๋ฒํค๋๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ ์งํ๊ธฐ ์ํด ๊ผญ ํ์ํ ๊ฒฝ์ฐ์๋ง ๋๊ธฐํํ์ญ์์ค. ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ ํ๋ฆ์ ์ ์คํ๊ฒ ๋ถ์ํ์ฌ ์ค์ํ ๋๊ธฐํ ์ง์ ์ ์๋ณํ์ญ์์ค.
- ์ ์ ํ ์ค๋ฅ ์ฒ๋ฆฌ: ์ ํ๋ฆฌ์ผ์ด์ ์ถฉ๋์ด๋ ์๊ธฐ์น ์์ ๋์์ ๋ฐฉ์งํ๊ธฐ ์ํด ํ์์์ ๋ฐ ์ค๋ฅ ์กฐ๊ฑด์ ์ ์ ํ ์ฒ๋ฆฌํ์ญ์์ค.
- ์น ์์ปค์ ํจ๊ป ์ฌ์ฉ: ๋ฌด๊ฑฐ์ด CPU ๊ณ์ฐ์ ์น ์์ปค๋ก ์คํ๋ก๋ํ์ญ์์ค. ๊ทธ๋ฐ ๋ค์ WebGL ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์ธ ์ค๋ ๋์์ ๋ฐ์ดํฐ ์ ์ก์ ๋๊ธฐํํ์ฌ ๋ค๋ฅธ ์ปจํ ์คํธ ๊ฐ์ ์ํํ ๋ฐ์ดํฐ ํ๋ฆ์ ๋ณด์ฅํ์ญ์์ค. ์ด ๊ธฐ์ ์ ๋ณต์กํ ๋ ๋๋ง ์์ ์ด๋ ๋ฌผ๋ฆฌ ์๋ฎฌ๋ ์ด์ ์ ํนํ ์ ์ฉํฉ๋๋ค.
- ํ๋กํ์ผ๋ง ๋ฐ ์ต์ ํ: WebGL ํ๋กํ์ผ๋ง ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋๊ธฐํ ๋ณ๋ชฉ ํ์์ ์๋ณํ๊ณ ๊ทธ์ ๋ฐ๋ผ ์ฝ๋๋ฅผ ์ต์ ํํ์ญ์์ค. Chrome ๊ฐ๋ฐ์ ๋๊ตฌ์ ์ฑ๋ฅ ํญ์ ์ด๋ฅผ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ๋๊ธฐํ ๊ฐ์ฒด ๋๊ธฐ์ ์์๋๋ ์๊ฐ์ ์ธก์ ํ๊ณ ๋๊ธฐํ๋ฅผ ์ค์ด๊ฑฐ๋ ์ต์ ํํ ์ ์๋ ์์ญ์ ์๋ณํ์ญ์์ค.
- ๋์ฒด ๋๊ธฐํ ๋ฉ์ปค๋์ฆ ๊ณ ๋ ค: ๋๊ธฐํ ๊ฐ์ฒด๋ ๊ฐ๋ ฅํ์ง๋ง, ํน์ ์ํฉ์์๋ ๋ค๋ฅธ ๋ฉ์ปค๋์ฆ์ด ๋ ์ ์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ฑ๋ฅ ๋น์ฉ์ด ๋ค๊ธฐ๋ ํ์ง๋ง ๋ ๊ฐ๋จํ ๋๊ธฐํ ์๊ตฌ์๋ `gl.flush()` ๋๋ `gl.finish()`๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ์ถฉ๋ถํ ์ ์์ต๋๋ค.
WebGL ๋๊ธฐํ ๊ฐ์ฒด์ ํ๊ณ
๊ฐ๋ ฅํ์ง๋ง, WebGL ๋๊ธฐํ ๊ฐ์ฒด์๋ ๋ช ๊ฐ์ง ํ๊ณ๊ฐ ์์ต๋๋ค:
- `gl.clientWaitSync()`์ ์ฐจ๋จ: `gl.clientWaitSync()`๋ฅผ ์ง์ ์ฌ์ฉํ๋ฉด ๋ฉ์ธ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ์ฌ UI ๋ฐ์์ฑ์ ์ ํดํฉ๋๋ค. ๋น๋๊ธฐ ๋์์ด ํ์์ ์ ๋๋ค.
- ์ค๋ฒํค๋: ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ค๋ฒํค๋๋ฅผ ์ ๋ฐํ๋ฏ๋ก ์ ์คํ๊ฒ ์ฌ์ฉํด์ผ ํฉ๋๋ค. ๋๊ธฐํ์ ์ด์ ๊ณผ ์ฑ๋ฅ ๋น์ฉ์ ๋น๊ต ํ๊ฐํ์ญ์์ค.
- ๋ณต์ก์ฑ: ์ ์ ํ ๋๊ธฐํ๋ฅผ ๊ตฌํํ๋ฉด ์ฝ๋์ ๋ณต์ก์ฑ์ด ์ถ๊ฐ๋ ์ ์์ต๋๋ค. ์ฒ ์ ํ ํ ์คํธ์ ๋๋ฒ๊น ์ด ํ์์ ์ ๋๋ค.
- ์ ํ๋ ๊ฐ์ฉ์ฑ: ๋๊ธฐํ ๊ฐ์ฒด๋ ์ฃผ๋ก WebGL 2์์ ์ง์๋ฉ๋๋ค. WebGL 1์์๋ `EXT_disjoint_timer_query`์ ๊ฐ์ ํ์ฅ ๊ธฐ๋ฅ์ด GPU ์๊ฐ์ ์ธก์ ํ๊ณ ๊ฐ์ ์ ์ผ๋ก ์๋ฃ๋ฅผ ์ถ๋ก ํ๋ ๋์ฒด ๋ฐฉ๋ฒ์ ์ ๊ณตํ ์ ์์ง๋ง, ์ด๋ ์ง์ ์ ์ธ ๋์ฒด ์๋จ์ด ์๋๋๋ค.
๊ฒฐ๋ก
WebGL ๋๊ธฐํ ๊ฐ์ฒด๋ ๊ณ ์ฑ๋ฅ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์ GPU-CPU ๋๊ธฐํ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ํ์์ ์ธ ๋๊ตฌ์ ๋๋ค. ๊ทธ ๊ธฐ๋ฅ, ๊ตฌํ ์ธ๋ถ ์ ๋ณด, ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ดํดํจ์ผ๋ก์จ ๋ฐ์ดํฐ ๊ฒฝ์์ ํจ๊ณผ์ ์ผ๋ก ๋ฐฉ์งํ๊ณ , ์ง์ฐ์ ์ค์ด๋ฉฐ, WebGL ํ๋ก์ ํธ์ ์ ๋ฐ์ ์ธ ์ฑ๋ฅ์ ์ต์ ํํ ์ ์์ต๋๋ค. ๋น๋๊ธฐ ๊ธฐ์ ์ ์ฑํํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๊ตฌ ์ฌํญ์ ์ ์คํ๊ฒ ๋ถ์ํ์ฌ ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๊ณ , ์ ์ธ๊ณ ์ฌ์ฉ์๋ค์๊ฒ ๋งค๋๋ฝ๊ณ ๋ฐ์์ฑ์ด ์ข์ผ๋ฉฐ ์๊ฐ์ ์ผ๋ก ๋๋ผ์ด ์น ๊ฒฝํ์ ๋ง๋ค์ด๋ด์ญ์์ค.
๋ ์์๋ณด๊ธฐ
WebGL ๋๊ธฐํ ๊ฐ์ฒด์ ๋ํ ์ดํด๋ฅผ ๋์ด๋ ค๋ฉด ๋ค์ ์๋ฃ๋ฅผ ํ์ํด ๋ณด์ญ์์ค:
- WebGL ๋ช ์ธ์: ๊ณต์ WebGL ๋ช ์ธ์๋ ๋๊ธฐํ ๊ฐ์ฒด์ ๊ทธ API์ ๋ํ ์์ธ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค.
- OpenGL ๋ฌธ์: WebGL ๋๊ธฐํ ๊ฐ์ฒด๋ OpenGL ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ฏ๋ก, OpenGL ๋ฌธ์์์ ๊ท์คํ ํต์ฐฐ๋ ฅ์ ์ป์ ์ ์์ต๋๋ค.
- WebGL ํํ ๋ฆฌ์ผ ๋ฐ ์์ : ๋ค์ํ ์๋๋ฆฌ์ค์์ ๋๊ธฐํ ๊ฐ์ฒด์ ์ค์ ์ฌ์ฉ๋ฒ์ ๋ณด์ฌ์ฃผ๋ ์จ๋ผ์ธ ํํ ๋ฆฌ์ผ ๋ฐ ์์ ๋ฅผ ํ์ํด ๋ณด์ญ์์ค.
- ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ: ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ WebGL ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋กํ์ผ๋งํ๊ณ ๋๊ธฐํ ๋ณ๋ชฉ ํ์์ ์๋ณํ์ญ์์ค.
WebGL ๋๊ธฐํ ๊ฐ์ฒด๋ฅผ ๋ฐฐ์ฐ๊ณ ์คํํ๋ ๋ฐ ์๊ฐ์ ํฌ์ํจ์ผ๋ก์จ WebGL ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ํฌ๊ฒ ํฅ์์ํฌ ์ ์์ต๋๋ค.